<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Using the REST Client with Multipart</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/rest-client-multipart" />
  <meta property="og:title" content="Quarkus - Using the REST Client with Multipart" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/rest-client-multipart">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Using the REST Client with Multipart</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#solution">Solution</a></li>
<li><a href="#creating-the-maven-project">Creating the Maven project</a></li>
<li><a href="#setting-up-the-model">Setting up the model</a></li>
<li><a href="#create-the-interface">Create the interface</a></li>
<li><a href="#create-the-configuration">Create the configuration</a></li>
<li><a href="#update-the-jax-rs-resource">Update the JAX-RS resource</a></li>
<li><a href="#creating-the-server">Creating the server</a></li>
<li><a href="#update-the-test">Update the test</a></li>
<li><a href="#package-and-run-the-application">Package and run the application</a></li>
<li><a href="#further-reading">Further reading</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>RESTEasy has rich support for the <code>multipart/*</code> and <code>multipart/form-data</code> mime types. The multipart mime format is used to pass lists of content bodies. Multiple content bodies are embedded in one message. <code>multipart/form-data</code> is often found in web application HTML Form documents and is generally used to upload files. The form-data format is the same as other multipart formats, except that each inlined piece of content has a name associated with it.</p>
</div>
<div class="paragraph">
<p>This guide explains how to use the MicroProfile REST Client with Multipart in order to interact with REST APIs
requiring multipart/form-data content-type with very little effort.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="prerequisites"><a class="anchor" href="#prerequisites"></a>Prerequisites</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To complete this guide, you need:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>less than 15 minutes</p>
</li>
<li>
<p>an IDE</p>
</li>
<li>
<p>JDK 1.8+ installed with <code>JAVA_HOME</code> configured appropriately</p>
</li>
<li>
<p>Apache Maven 3.6.2+</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="solution"><a class="anchor" href="#solution"></a>Solution</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We recommend that you follow the instructions in the next sections and create the application step by step.
However, you can go right to the completed example.</p>
</div>
<div class="paragraph">
<p>Clone the Git repository: <code>git clone <a href="https://github.com/quarkusio/quarkus-quickstarts.git" class="bare">https://github.com/quarkusio/quarkus-quickstarts.git</a></code>, or download an <a href="https://github.com/quarkusio/quarkus-quickstarts/archive/master.zip">archive</a>.</p>
</div>
<div class="paragraph">
<p>The solution is located in the <code>rest-client-multipart-quickstart</code> <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/master/rest-client-multipart-quickstart">directory</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-the-maven-project"><a class="anchor" href="#creating-the-maven-project"></a>Creating the Maven project</h2>
<div class="sectionbody">
<div class="paragraph">
<p>First, we need a new project. Create a new project with the following command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=rest-client-multipart-quickstart \
    -DclassName="org.acme.rest.client.multipart.MultipartClientResource" \
    -Dpath="/client" \
    -Dextensions="rest-client, resteasy"
cd rest-client-multipart-quickstart</code></pre>
</div>
</div>
<div class="paragraph">
<p>This command generates the Maven project with a REST endpoint and imports the <code>rest-client</code> and <code>resteasy</code> extensions.</p>
</div>
<div class="paragraph">
<p>Then, we&#8217;ll add the following dependency to support <code>multipart/form-data</code> requests:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;org.jboss.resteasy&lt;/groupId&gt;
    &lt;artifactId&gt;resteasy-multipart-provider&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="setting-up-the-model"><a class="anchor" href="#setting-up-the-model"></a>Setting up the model</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In this guide we will be demonstrating how to invoke a REST service accepting multipart/form-data input.
We are assuming the payload is well-known before the request is sent, so we can model as a POJO.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>If the payload is unknown, you can also use the RESTEasy custom API instead. If that&#8217;s the case, see the RESTEasy Multipart Providers link in the end of the guide.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Our first order of business is to setup the model we will be using to define the <code>multipart/form-data</code> payload, in the form of a <code>MultipartBody</code> POJO.</p>
</div>
<div class="paragraph">
<p>Create a <code>src/main/java/org/acme/rest/client/multipart/MultipartBody.java</code> file and set the following content:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.rest.client.multipart;

import java.io.InputStream;

import javax.ws.rs.FormParam;
import javax.ws.rs.core.MediaType;

import org.jboss.resteasy.annotations.providers.multipart.PartType;

public class MultipartBody {

    @FormParam("file")
    @PartType(MediaType.APPLICATION_OCTET_STREAM)
    public InputStream file;

    @FormParam("fileName")
    @PartType(MediaType.TEXT_PLAIN)
    public String fileName;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The purpose of the annotations in the code above is the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>@FormParam</code> is a standard JAX-RS annotation used to define a form parameter contained within a request entity body</p>
</li>
<li>
<p><code>@PartType</code> is a RESTEasy specific annotation required when a client performs a multipart request and defines the content type for the part.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="create-the-interface"><a class="anchor" href="#create-the-interface"></a>Create the interface</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Using the MicroProfile REST Client is as simple as creating an interface using the proper JAX-RS and MicroProfile annotations. In our case the interface should be created at <code>src/main/java/org/acme/rest/client/multipart/MultipartService.java</code> and have the following content:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.rest.client.multipart;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;

@Path("/echo")
@RegisterRestClient
public interface MultipartService {

    @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.TEXT_PLAIN)
    String sendMultipartData(@MultipartForm MultipartBody data);

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>sendMultipartData</code> method gives our code the ability to POST a <code>multipart/form-data</code> request to our Echo service (running in the same server for demo purposes).
Because in this demo we have the exact knowledge of the <code>multipart/form-data</code> packets, we can map them to the model class created in the previous section using the <code>@org.jboss.resteasy.annotations.providers.multipart.MultipartForm</code> annotation.</p>
</div>
<div class="paragraph">
<p>The client will handle all the networking and marshalling leaving our code clean of such technical details.</p>
</div>
<div class="paragraph">
<p>The purpose of the annotations in the code above is the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>@RegisterRestClient</code> allows Quarkus to know that this interface is meant to be available for
CDI injection as a REST Client</p>
</li>
<li>
<p><code>@Path</code>, <code>@GET</code> and <code>@PathParam</code> are the standard JAX-RS annotations used to define how to access the service</p>
</li>
<li>
<p><code>@MultipartForm</code> defines the parameter as a value object for incoming/outgoing request/responses of the multipart/form-data mime type.</p>
</li>
<li>
<p><code>@Consumes</code> defines the expected content-type consumed by this request (parameters)</p>
</li>
<li>
<p><code>@Produces</code> defines the expected content-type produced by this request (return type)</p>
</li>
</ul>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>While <code>@Consumes</code> and <code>@Produces</code> are optional as auto-negotiation is supported,
it is heavily recommended to annotate your endpoints with them to define precisely the expected content-types.</p>
</div>
<div class="paragraph">
<p>It will allow to narrow down the number of JAX-RS providers (which can be seen as converters) included in the native executable.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="create-the-configuration"><a class="anchor" href="#create-the-configuration"></a>Create the configuration</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In order to determine the base URL to which REST calls will be made, the REST Client uses configuration from <code>application.properties</code>.
The name of the property needs to follow a certain convention which is best displayed in the following code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs"># Your configuration properties
org.acme.rest.client.multipart.MultipartService/mp-rest/url=http://localhost:8080/</code></pre>
</div>
</div>
<div class="paragraph">
<p>Having this configuration means that all requests performed using <code>org.acme.rest.client.multipart.MultipartService</code> will use `http://localhost:8080/ ` as the base URL.</p>
</div>
<div class="paragraph">
<p>Note that <code>org.acme.rest.client.multipart.MultipartService</code> <em>must</em> match the fully qualified name of the <code>MultipartService</code> interface we created in the previous section.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="update-the-jax-rs-resource"><a class="anchor" href="#update-the-jax-rs-resource"></a>Update the JAX-RS resource</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Open the <code>src/main/java/org/acme/rest/client/multipart/MultipartClientResource.java</code> file and update it with the following content:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.rest.client.multipart;

import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;

import javax.inject.Inject;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.eclipse.microprofile.rest.client.inject.RestClient;

@Path("/client")
public class MultipartClientResource {

    @Inject
    @RestClient
    MultipartService service;

    @POST
    @Path("/multipart")
    @Produces(MediaType.TEXT_PLAIN)
    public String sendFile() throws Exception {
        MultipartBody body = new MultipartBody();
        body.fileName = "greeting.txt";
        body.file = new ByteArrayInputStream("HELLO WORLD".getBytes(StandardCharsets.UTF_8));
        return service.sendMultipartData(body);
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that in addition to the standard CDI <code>@Inject</code> annotation, we also need to use the MicroProfile <code>@RestClient</code> annotation to inject <code>MultipartService</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-the-server"><a class="anchor" href="#creating-the-server"></a>Creating the server</h2>
<div class="sectionbody">
<div class="paragraph">
<p>For demo purposes, let&#8217;s create a simple Echo endpoint that will act as the server part.</p>
</div>
<div class="paragraph">
<p>Create the directory <code>src/main/java/org/acme/rest/client/multipart/server</code> and include a <code>EchoService.java</code> file with the following content:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.rest.client.multipart.server;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/echo")
public class EchoService {

    @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.TEXT_PLAIN)
    public String echo(String requestBody) throws Exception {
        return requestBody;
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will just return the request body and it&#8217;s useful for testing purposes.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="update-the-test"><a class="anchor" href="#update-the-test"></a>Update the test</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We also need to update the functional test to reflect the changes made to the endpoint.
Edit the <code>src/test/java/org/acme/rest/client/multipart/MultipartResourceTest.java</code> file to:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.rest.client.multipart;

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.containsString;

@QuarkusTest
public class MultipartResourceTest {

    @Test
    public void testMultipartDataIsSent() {
        given()
                .when().post("/client/multipart")
                .then()
                .statusCode(200)
                .body( containsString("Content-Disposition: form-data; name=\"file\""),
                        containsString("HELLO WORLD"),
                        containsString("Content-Disposition: form-data; name=\"fileName\""),
                        containsString("greeting.txt"));
    }

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The code above uses <a href="http://rest-assured.io/">REST Assured</a> to assert that the returned content from the echo service contains multipart elements</p>
</div>
<div class="paragraph">
<p>Because the test runs in a different port, we also need to include an <code>application.properties</code> in our <code>src/test/resources</code> with the following content:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs"># Your configuration properties
org.acme.rest.client.multipart.MultipartService/mp-rest/url=http://localhost:8081/</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="package-and-run-the-application"><a class="anchor" href="#package-and-run-the-application"></a>Package and run the application</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p>Run the application with: <code>./mvnw compile quarkus:dev</code>.</p>
</li>
<li>
<p>In a terminal, run <code>curl -X POST <a href="http://localhost:8080/client/multipart" class="bare">http://localhost:8080/client/multipart</a></code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>You should see an output similar to:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">--89d288bd-960f-460c-b266-64c5b4d170fa
Content-Disposition: form-data; name="fileName"
Content-Type: text/plain

greeting.txt
--89d288bd-960f-460c-b266-64c5b4d170fa
Content-Disposition: form-data; name="file"
Content-Type: application/octet-stream

HELLO WORLD
--89d288bd-960f-460c-b266-64c5b4d170fa--</code></pre>
</div>
</div>
<div class="paragraph">
<p>As usual, the application can be packaged using <code>./mvnw clean package</code> and executed using the <code>-runner.jar</code> file.
You can also generate the native executable with <code>./mvnw clean package -Pnative</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="further-reading"><a class="anchor" href="#further-reading"></a>Further reading</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p><a href="https://download.eclipse.org/microprofile/microprofile-rest-client-1.2.1/microprofile-rest-client-1.2.1.html">MicroProfile Rest Client specification</a></p>
</li>
<li>
<p><a href="https://docs.jboss.org/resteasy/docs/4.3.1.Final/userguide/html/Multipart.html">RESTEasy Multipart Providers</a></p>
</li>
</ul>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
